iT邦幫忙

2025 iThome 鐵人賽

DAY 21
0
Mobile Development

從零開始學習 iOS系列 第 21

從零開始學習 iOS Day20 - Swift 資料儲存基礎

  • 分享至 

  • xImage
  •  

在 App 開發中,資料的保存讀取是不可或缺的一環。不論是使用者的偏好設定、登入狀態,還是需要離線瀏覽的內容,都必須妥善存放。今天我們來介紹 iOS 上常見的幾種資料儲存方式。


為什麼需要資料儲存

  • 維持使用者體驗:例如使用者切換深色模式、上次播放的位置。
  • 離線使用:沒有網路時仍能瀏覽資料。
  • 效能最佳化:避免每次都重新請求伺服器。

iOS 常見的資料儲存方式

UserDefaults

  • 適合儲存:小量、簡單的資料(例如布林值、字串、整數)。
  • 特點:
    • Key-Value 形式。
    • 自動持久化(儲存後下次開啟 App 還存在)。
    • 不適合放大量或敏感資料。

範例:

// 儲存
UserDefaults.standard.set(true, forKey: "isDarkMode")
// 讀取
let isDarkMode = UserDefaults.standard.bool(forKey: "isDarkMode")


FileManager

  • 適合儲存:自訂結構的資料(JSON、圖片、檔案快取)。
  • 特點:
    • 由開發者決定存放位置(Documents、Caches、tmp)。
    • 適合需要序列化或大檔案的情境。

範例:儲存 JSON 檔

struct User: Codable {
    let name: String
    let age: Int
}

let user = User(name: "Jerry", age: 18)
let data = try JSONEncoder().encode(user)

let url = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    .appendingPathComponent("user.json")

try data.write(to: url)


Keychain (使用 KeychainAccess 套件)

  • 適合儲存:敏感資料(例如 Token、密碼)。
  • 特點:
    • Apple 提供的加密安全儲存。
    • 比 UserDefaults 更安全,專為憑證/金鑰/帳號密碼而設計。
import KeychainAccess

let keychain = Keychain(service: "com.example.MyApp")

// 儲存
do {
    try keychain.set("secret_token_123", key: "userToken")
} catch {
    print("Keychain 儲存失敗: \(error)")
}

// 讀取
do {
    let token = try keychain.get("userToken")
    print("取得 token: \(token ?? "無")")
} catch {
    print("Keychain 讀取失敗: \(error)")
}

// 刪除
do {
    try keychain.remove("userToken")
} catch {
    print("Keychain 刪除失敗: \(error)")
}

CoreData

  • 適合儲存:大量、結構化的資料
  • 特點:
    • Apple 提供的 ORM(Object Relational Mapping)。
    • 可以用類似操作物件的方式,完成資料表格的 CRUD。
    • 支援關聯、查詢、版本遷移。
    • 學習成本較高,但功能完整。

建立 Model

假設你有一個Item的Entity,包含timestamp: Date

@Environment(\.managedObjectContext) private var viewContext

private func addItem() {
    withAnimation {
        let newItem = Item(context: viewContext)
        newItem.timestamp = Date()

        do {
            try viewContext.save()
        } catch {
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }
}

func fetchItems() -> [Item] {
		let request = Item.fetchRequest()
    do {
        let items = try viewContext.fetch(request)
        return items
    } catch {
        print("Core Data 讀取失敗: \(error)")
        return []
    }
}

SwiftData

  • 把CoreData封裝,更符合 Swift 語言風格。
  • 特點
    • 針對 Swift 語法優化。
    • 學習成本較低,貼近 SwiftUI + Swift 的寫法
    • 僅支援 iOS 17+、macOS 14+
@Model
class ItemModel {
    var timestamp: Date
    
    init(timestamp: Date) {
        self.timestamp = timestamp
    }
}

struct SwiftDataExampletView: View {
    @Environment(\.modelContext) private var modelContext
    @Query(sort: \ItemModel.timestamp) var items: [ItemModel]

    var body: some View {
        VStack {
            List(items, id: \.timestamp) { item in
                Text("\(item.timestamp)")
            }
            
            Button("新增 Date") {
                let newPerson = ItemModel(timestamp: Date())
                modelContext.insert(newPerson)
            }
        }
    }
}

#Preview {
    SwiftDataExampletView()
        .modelContainer(for: ItemModel.self)
}

今日小結

  • 小量簡單資料UserDefaults
  • 檔案、JSON、圖片FileManager
  • 敏感資訊Keychain
  • 大量結構化資料Core Data

今天我們介紹了 iOS 常見的資料儲存基礎方式,從最簡單的 UserDefaults 到進階的 Core Data


上一篇
從零開始學習 iOS Day19 - async/await 與串接 API
下一篇
從零開始學習 iOS Day21 - Push Notification
系列文
從零開始學習 iOS24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言